package com.huluobo.a2204kotlinjetpackdemo.coroutine

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import com.huluobo.a2204kotlinjetpackdemo.R
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.w3c.dom.Text
import java.lang.Exception

class CoroutineActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_coroutine)

//        //创建协程,相当于newThread
//        val job = GlobalScope.launch(Dispatchers.IO) {
//            Log.i("TagA", "当前线程:${Thread.currentThread().name}")
//        }
//
//        job.cancel()
//        GlobalScope.launch(Dispatchers.Main) {
//            Log.i("TagA", "当前线程:${Thread.currentThread().name}")
//        }
        //全局的协程作用域尽量不要用

        //工作对象
        val job = Job()
        CoroutineScope(job).launch {
//            val result = async {
//                try {
//                    //模拟发起请求
//                    delay(3000)
//                    "运算结果:${3 / 1}"
//                } catch (e: Exception) {
//                    "结果异常"
//                }
//            }.await()
//            Log.i("TagA", result)

            val startTime = System.currentTimeMillis()
            val result = async {
                delay(2000)
                "操作成功"
            }

            val result2 = async {
                delay(1000)
                "获取成功"
            }
            Log.i("TagA", "执行结果:${result.await()} ,${result2.await()}")
            val endTime = System.currentTimeMillis()
            Log.i("TagA", "执行时间:${endTime - startTime}")
            //出现执行3秒的过程,因为result执行完成后,会直接执行result2,造成线程阻塞,所以时间会相加
            //程序是按照上下顺序来执行的,当在过程中调用await时,会造成当前线程的阻塞,所以是同步执行的,造成结果时间会叠加是3秒
            //如果在结果中调用await,这时是异步执行的,就不会造成时间的叠加,也就是不会阻塞线程
        }

        CoroutineScope(job).launch {
            loadData()
        }

        CoroutineScope(job).launch(Dispatchers.Main) {
            //Dispatchers.Main 表示在程序主线程中运行,所以在开启协程时,他的代码不一定是在子线程中执行的,也可以随时进行切换
            //Dispatchers.IO 常用语耗时操作,比如网络请求,文件读写等
            //Dispatchers.Default 表示默认,协程交给系统处理,一般用于计算密集型
            val result = withContext(Dispatchers.IO) {
                delay(2000)
                "操作成功"
            }
            Log.i("TagA", result)
        }

        loadDataFromNet()
    }

    //系统并不知道一个方法是否会在协程中执行,所以需要加上suspend(挂起)来提示其他开发者,当方法需要放到协程中调用时,必须加上挂起的修饰符
    private suspend fun loadData() {
        delay(2000)
        Log.i("TagA", "loadData")
    }

    private fun loadDataFromNet() {
//        Thread {
//            //执行网络请求获得结果
//            runOnUiThread {
//                //切换到UI线程更新UI
//            }
//        }
        val job = Job()
        CoroutineScope(job).launch(Dispatchers.Main) {
            val result = withContext(Dispatchers.IO) {
                delay(2000)
                "获取网络成功"
            }
            showUI(result)

//            val result2=  withContext(Dispatchers.Main){
//                delay(15000).63
//                "延时15秒"
//            }
//            Log.i("TagA","result2:$result2")
        }
    }

    private fun showUI(result: String) {
        val tv = findViewById<TextView>(R.id.tv)
        tv.text = result
    }
}